using System;
using NUnit.Framework;

namespace fp.parser.tests
{
  [TestFixture]
  public class TestParser
  {
    private static void DumpAST(Parser node, int i)
    {
      if (node == null) return;
      Console.WriteLine("{0}{1} / {2}", "".PadLeft(i, ' '), node.term, node.typ);

      DumpAST(node.childLeft, i++);
      DumpAST(node.childRight, i);
    }

    public void Differenziation3() // e^x
    {
      var parser = new Parser();
      parser.Parse("e^(3*x)");
      var result = parser.Differenziere();
      Assert.AreEqual("3*e^(3*x)", result);
    }

    [Test]
    public void Differenziation() // ln
    {
      var parser = new Parser();
      parser.Parse("ln(3*x)");
      var result = parser.Differenziere();
      Assert.AreEqual("1/(3*x)*3", result);
    }

    [Test]
    public void Differenziation2() // ln
    {
      var parser = new Parser();
      parser.Parse("ln(3/x)");
      var result = parser.Differenziere();
      Assert.AreEqual("1/(3/x)*(-3)/x^2", result);
    }

    [Test]
    public void Integration()
    {
      var parser = new Parser();
      parser.Parse("7*x^3");
      var result = parser.Integriere();
      Assert.AreEqual("1,75*x^4", result);
    }

    [Test]
    public void TestAST()
    {
      var parser = new Parser();
      var ast = parser.Parse("2+3*4");

      DumpAST(ast, 0);
    }


    [Test]
    public void Zusammenfassen() // Addition
    {
      var parser = new Parser();
      parser.Parse("3*x+4*x");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("7*x", result);
    }

    [Test]
    public void Zusammenfassen1() // Subtraktion
    {
      var parser = new Parser();
      parser.Parse("3*x-4*x");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("-1*x", result);
    }

    [Test]
    public void Zusammenfassen2() // Multiplikation
    {
      var parser = new Parser();
      parser.Parse("(x^2-2*x^2)*(4*x+8*x)");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("(-1*x^2)*12*x", result);
    }

    [Test]
    public void Zusammenfassen3() // Division
    {
      var parser = new Parser();
      parser.Parse("1/(3*x+4*x)");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("1/(7*x)", result);
    }

    [Test]
    public void Zusammenfassen3a() // Division
    {
      var parser = new Parser();
      parser.Parse("(3*x+6*x)/(3*x+4*x)");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("(9*x)/(7*x)", result);
    }

    [Test]
    public void Zusammenfassen4() // Potenzieren
    {
      var parser = new Parser();
      parser.Parse("(3*x+7*x)^(2*x)");
      var result = parser.Zusammenfassen(true);
      Assert.AreEqual("(10*x)^(2*x)", result);
    }
  }
}